// .........................................................................
// Title: drawdowns_sample.do
//
// Computes drawdowns for bonds in the baseline US sample, creates merged
// panel of drawdowns and bond characteristics for analysis
// .........................................................................

* ---------------------------------------
* Compute drawdowns: Great Recession (gr)
* ---------------------------------------

* Prepare data for drawdown estimation
use "$tmp/trace_enhanced_clean_returns_hedged_w", clear
gsort cusip date
bys cusip: egen min_date = min(date)
bys cusip: egen max_date = max(date)
format %tw min_date max_date

keep if min_date <= $min_security_window_w
keep if max_date >= $max_security_window_w
keep if date_w <= $max_security_window_w
keep if date_w >= $min_security_window_w

by cusip: egen has_trading_gaps = max(trading_gap)

gen log_return = log(1 + net_return)
gen log_hedged_return = log(1 + hedged_return)

by cusip: gen cum_log_return = 1 + sum(log_return)
by cusip: gen cum_log_hedged_return = 1 + sum(log_hedged_return)

gen cum_return = exp(cum_log_return) - 1
gen cum_hedged_return = exp(cum_log_hedged_return) - 1

by cusip: egen min_h = min(cum_hedged_return)
by cusip: egen max_h = max(cum_hedged_return)
replace cum_hedged_return = . if min_h == max_h == 1

keep cusip date_w cum_return cum_hedged_return has_trading_gaps
save "$tmp/event_forpy_gr", replace

* Run drawdown estimation
shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_gr.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_return" ///
    --out_file "$tmp/drawdowns_frompy_gr.dta"

shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_gr.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_hedged_return" ///
    --out_file "$tmp/drawdowns_frompy_gr_hedged.dta"

* ---------------------------------------
* Compute drawdowns: COVID event
* ---------------------------------------

* Prepare data for drawdown estimation
use "$tmp/trace_enhanced_clean_returns_hedged_w", clear
gsort cusip date
bys cusip: egen min_date = min(date)
bys cusip: egen max_date = max(date)
format %td min_date max_date

keep if min_date <= $min_security_window_covid_w
keep if max_date >= $max_security_window_covid_w
keep if date <= $max_security_window_covid_w
keep if date >= $min_security_window_covid_w

by cusip: egen has_trading_gaps = max(trading_gap)

gen log_return = log(1 + net_return)
gen log_hedged_return = log(1 + hedged_return)

by cusip: gen cum_log_return = 1 + sum(log_return)
by cusip: gen cum_log_hedged_return = 1 + sum(log_hedged_return)

gen cum_return = exp(cum_log_return) - 1
gen cum_hedged_return = exp(cum_log_hedged_return) - 1

by cusip: egen min_h = min(cum_hedged_return)
by cusip: egen max_h = max(cum_hedged_return)
replace cum_hedged_return = . if min_h == max_h == 1

keep cusip date_w cum_return cum_hedged_return has_trading_gaps
save "$tmp/event_forpy_covid", replace

* Run drawdown estimation
shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_covid.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_return" ///
    --out_file "$tmp/drawdowns_frompy_covid.dta"

shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_covid.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_hedged_return" ///
    --out_file "$tmp/drawdowns_frompy_covid_hedged.dta"

* ---------------------------------------
* Compute drawdowns: 2016 event (p16)
* ---------------------------------------

* Prepare data for drawdown estimation
use "$tmp/trace_enhanced_clean_returns_hedged_w", clear
gsort cusip date
bys cusip: egen min_date = min(date)
bys cusip: egen max_date = max(date)
format %td min_date max_date

keep if min_date <= $min_security_window_p16_w
keep if max_date >= $max_security_window_p16_w
keep if date <= $max_security_window_p16_w
keep if date >= $min_security_window_p16_w

by cusip: egen has_trading_gaps = max(trading_gap)

gen log_return = log(1 + net_return)
gen log_hedged_return = log(1 + hedged_return)

by cusip: gen cum_log_return = 1 + sum(log_return)
by cusip: gen cum_log_hedged_return = 1 + sum(log_hedged_return)

gen cum_return = exp(cum_log_return) - 1
gen cum_hedged_return = exp(cum_log_hedged_return) - 1

by cusip: egen min_h = min(cum_hedged_return)
by cusip: egen max_h = max(cum_hedged_return)
replace cum_hedged_return = . if min_h == max_h == 1

keep cusip date_w cum_return cum_hedged_return has_trading_gaps
save "$tmp/event_forpy_p16", replace

* Run drawdown estimation
shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_p16.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_return" ///
    --out_file "$tmp/drawdowns_frompy_p16.dta"

shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_p16.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_hedged_return" ///
    --out_file "$tmp/drawdowns_frompy_p16_hedged.dta"

* ---------------------------------------
* Compute drawdowns: 2011 event (p11)
* ---------------------------------------

* Prepare data for drawdown estimation
use "$tmp/trace_enhanced_clean_returns_hedged_w", clear
gsort cusip date
bys cusip: egen min_date = min(date)
bys cusip: egen max_date = max(date)
format %td min_date max_date

keep if min_date <= $min_security_window_p11_w
keep if max_date >= $max_security_window_p11_w
keep if date <= $max_security_window_p11_w
keep if date >= $min_security_window_p11_w

by cusip: egen has_trading_gaps = max(trading_gap)

gen log_return = log(1 + net_return)
gen log_hedged_return = log(1 + hedged_return)

by cusip: gen cum_log_return = 1 + sum(log_return)
by cusip: gen cum_log_hedged_return = 1 + sum(log_hedged_return)

gen cum_return = exp(cum_log_return) - 1
gen cum_hedged_return = exp(cum_log_hedged_return) - 1

by cusip: egen min_h = min(cum_hedged_return)
by cusip: egen max_h = max(cum_hedged_return)
replace cum_hedged_return = . if min_h == max_h == 1

keep cusip date_w cum_return cum_hedged_return has_trading_gaps
save "$tmp/event_forpy_p11", replace

* Run drawdown estimation
shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_p11.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_return" ///
    --out_file "$tmp/drawdowns_frompy_p11.dta"

shell $python_interpreter_path $code_path/scripts/compute_drawdowns.py ///
    --input_file "$tmp/event_forpy_p11.dta" ///
    --id_field "cusip" ///
    --date_field "date_w" ///
    --price_field "cum_hedged_return" ///
    --out_file "$tmp/drawdowns_frompy_p11_hedged.dta"

* ---------------------------------------
* Fixed-window drawdowns variant
* ---------------------------------------

* Estimate fixed-window drawdowns
foreach event in "gr" "covid" "p16" "p11" {
    use "$tmp/event_forpy_`event'", clear
    gsort cusip date_w
    by cusip: keep if _n == 1 | _n == _N
    by cusip: gen t = _n
    keep cusip cum_hedged_return t
    reshape wide cum_hedged_return, i(cusip) j(t)
    gen fw_hedged_drawdown = max(0, 1 - cum_hedged_return2 / cum_hedged_return1)
    save "$tmp/fw_drawdowns_`event'", replace
}

* ---------------------------------------
* Merge drawdowns and holdings data
* ---------------------------------------

* Append files
foreach event in "gr" "covid" "p16" "p11" {
    use "$tmp/drawdowns_frompy_`event'.dta", clear
    rename py_drawdown drawdown
    mmerge cusip using "$tmp/drawdowns_frompy_`event'_hedged.dta", uname(u_) ukeep(py_drawdown)
    rename u_py_drawdown drawdown_hedged
    cap drop index
    cap drop _merge
    save "$tmp/drawdowns_py_`event'", replace
}

* Merge drawdowns and holdings: great recession
use "$tmp/drawdowns_py_gr", clear
mmerge cusip using "$tmp/ex_ante_positions_great_recession", unmatched(m)
keep if _merge == 3
mmerge cusip using "$tmp/fw_drawdowns_gr.dta", unmatched(m)
drop _merge
gen year = year(dofm($ex_ante_positions_m))
gen event = "great_recession"
gen date_m = $ex_ante_positions_m
format %tm date_m
save "$tmp/drawdown_holdings_gr_cov", replace

* Merge drawdowns and holdings: covid
use "$tmp/drawdowns_py_covid", clear
mmerge cusip using "$tmp/ex_ante_positions_covid", unmatched(m)
keep if _merge == 3
mmerge cusip using "$tmp/fw_drawdowns_covid.dta", unmatched(m)
drop _merge
gen year = year(dofm($ex_ante_positions_covid_m))
gen event = "covid"
gen date_m = $ex_ante_positions_covid_m
format %tm date_m
save "$tmp/drawdown_holdings_covid_cov", replace

* Merge drawdowns and holdings: p16
use "$tmp/drawdowns_py_p16", clear
mmerge cusip using "$tmp/ex_ante_positions_p16", unmatched(m)
keep if _merge == 3
mmerge cusip using "$tmp/fw_drawdowns_p16.dta", unmatched(m)
drop _merge
gen year = year(dofm($ex_ante_positions_p16_m))
gen event = "p16"
gen date_m = $ex_ante_positions_p16_m
format %tm date_m
save "$tmp/drawdown_holdings_p16_cov", replace

* Merge drawdowns and holdings: p11
use "$tmp/drawdowns_py_p11", clear
mmerge cusip using "$tmp/ex_ante_positions_p11", unmatched(m)
keep if _merge == 3
mmerge cusip using "$tmp/fw_drawdowns_p11.dta", unmatched(m)
drop _merge
gen year = year(dofm($ex_ante_positions_p11_m))
gen event = "p11"
gen date_m = $ex_ante_positions_p11_m
format %tm date_m
save "$tmp/drawdown_holdings_p11_cov", replace

* Merge all dataframes
clear
append using "$tmp/drawdown_holdings_gr_cov"
append using "$tmp/drawdown_holdings_covid_cov"
append using "$tmp/drawdown_holdings_p16_cov"
append using "$tmp/drawdown_holdings_p11_cov"
cap drop _merge
save "$tmp/drawdown_holdings_all_cov", replace

* ---------------------------------------
* Add characteristics to the panel
* ---------------------------------------

* add characteristics
use "$tmp/drawdown_holdings_all_cov", clear

* add duration and other bond characteristics
mmerge cusip using "$tmp/ciq_static_characteristics_processed", unmatched(m)
mmerge cusip using "$tmp/consolidated_static_dummies", unmatched(m) ukeep(bc_is_senior bc_is_floating bc_is_callable) update
mmerge cusip date_m using "$tmp/duration_merged", unmatched(m)
drop _merge
cap drop R_* N_*
gen_duration_category
gen ones = 1

* update parent aggregation
gen issuer_number = substr(cusip, 1, 6)
mmerge issuer_number using "$raw/cmns/cmns_aggregation", unmatched(m) update
drop _merge *source*

* add mergent issuer ids
mmerge cusip using "$tmp/mergent_issuer_ids.dta", unmatched(m)

* merging in size
mmerge cusip year using "$tmp/amounts_outstanding_y_mv", unmatched(m)

* merging in ratings
mmerge cusip year using "$tmp/issue_ratings_merged_sp_moodys_y", unmatched(m)

* merging in associated issuers file
mmerge issuer_number using "$output/cgs/cgs_ai_aggregation", unmatched(m) umatch(cusip6) ukeep(ai_cusip6)
replace ai_cusip6 = issuer_number if missing(ai_cusip6)

* size deciles
gen log_value = log(value_outstanding)
egen log_value_decile = xtile(log_value), nq(10)

* consolidated issuer ids
gen consolidated_issuer_id = mergent_issuer_id
tostring consolidated_issuer_id, replace
replace consolidated_issuer_id = ai_cusip6 if missing(consolidated_issuer_id)
assert ~missing(consolidated_issuer_id)

* keep investment grade only
keep if inlist(rating_cat, "AAA", "AA", "A", "BBB")

* drop datapoints with missing values
assert ~missing(event)
drop if missing(rating_cat_pm) | missing(drn_bucket) | missing(bc_is_floating) | missing(bc_is_senior) ///
    | missing(bc_is_callable) | missing(consolidated_issuer_id) | missing(log_value_decile)

* encode event
encode event, gen(_event)

* full fixed effects category definition
egen full_fe_category = group(_event consolidated_issuer_id rating_cat_pm drn_bucket bc_is_floating ///
    bc_is_senior bc_is_callable log_value_decile)

* additional category definitions
egen fdr_event = group(_event consolidated_issuer_id rating_cat_pm drn_bucket log_value_decile)
egen firm_duration_event = group(_event consolidated_issuer_id drn_bucket log_value_decile)
egen firm_event = group(_event consolidated_issuer_id log_value_decile)
egen duration_rating_event = group(_event rating_cat_pm drn_bucket log_value_decile)
egen rating_event = group(_event rating_cat_pm log_value_decile)
egen duration_event = group(_event drn_bucket log_value_decile)

* clustering level
egen firm_event_cluster = group(consolidated_issuer_id _event)

* sanity check
gsort event cusip
order event cusip
by event cusip: gen N = _N
assert N == 1
drop N

gen nonfund_share = 1 - share_mf_issuance

keep event cusip drawdown drawdown_hedged holdings_mf_foreign issuer_name cgs_domicile cusip6_up_bg country_bg ///
    issuer_name_up class_code2 value_outstanding value_outstanding_mv tot_holdings share_ins_holdings share_ins_issuance holdings_by_issuance ///
    duration_y duration_m drn_bucket value_outstanding value_outstanding_mv full_fe_category fdr_event firm_duration_event firm_event ///
    duration_rating_event rating_event duration_event firm_event_cluster bc_is_floating bc_is_senior bc_is_callable log_value_decile ///
    bc_is_144a date_m share_ins_issuance_noaig consolidated_issuer_id rating_cat_pm nonfund_share

* save the data
save "$tmp/event_regframe_covariates", replace
